# coding: utf-8
'''
Description: git代码管理
version: 1.0.0
Author: peng2.zhang
Date: 2020-09-17 09:55:15
LastEditors: peng2.zhang
LastEditTime: 2022-01-23 10:30:19
'''
import re
import gitlab
from urllib.parse import urlparse
from urllib.parse import urljoin
import requests

class GitManage(object):
    url = "https://git.ecarxgroup.com"
    # token = "V6w6ocyhWTN8gax1q6aw"

    def __init__(self, git_name, git_commit_id="", git_branch_name="", git_token=""):
        if not git_token:
            self.token = "V6w6ocyhWTN8gax1q6aw"
        else:
            self.token = git_token
        self.git_name = git_name
        print(f"git_token: {self.token}")
        if ".git" in git_name:
            self.search_git_name = re.compile("(\S+)\.git").findall(self.git_name.split("/")[-1])[0]
        else:
            self.search_git_name = self.git_name
        projectID = self.get_git_project_id(self.search_git_name, git_token=self.token)
        self.projectID = projectID
        self.git = gitlab.Gitlab(self.url, self.token)
        self.project = self.git.projects.get(projectID)
        self.git_commit_id = git_commit_id
        self.git_branch_name = git_branch_name
        print(f"git_branch_name: {self.git_branch_name}")
    
    def get_git_project_id(self, search_git_name, git_token):
        # git_token = self.git_token or "V6w6ocyhWTN8gax1q6aw"
        url = self.url
        search_url = urljoin(url, f"api/v4/projects?search={search_git_name}")
        headers = {"PRIVATE-TOKEN": git_token}
        res = requests.get(search_url, headers=headers)
        search_list = res.json()
        # from code import interact
        # interact(local=locals())
        search_list = [i for i in search_list if i["ssh_url_to_repo"] == self.git_name or i["http_url_to_repo"] == self.git_name]
        if len(search_list) > 0:
            git_json = search_list[0]
            git_project_id = git_json["id"]
            return git_project_id
        else:
            raise ValueError()
    
    def branches(self):
        # return self.project.branches.list()
        headers = {
            "PRIVATE-TOKEN": self.token
        }
        path = "/api/v4/projects/%s/repository/branches?per_page=100" % self.projectID
        full_url = urljoin(self.url, path)
        res = requests.get(full_url, headers=headers)
        branches = sorted(res.json(),key = lambda b:(b['commit']['created_at'],b['name']),reverse = True)
        return branches
    
    def getLatestBranch(self):
        if "origin" in self.git_branch_name:
            full_branch_name = self.git_branch_name
            short_branch_name = self.git_branch_name.split("/")[-1]
        else:
            full_branch_name = f"origin/{self.git_branch_name}"
            short_branch_name = self.git_branch_name
        if self.git_branch_name:
            branches = [i for i in self.branches() if i["name"] == full_branch_name or i["name"] == short_branch_name]
            if len(branches) > 0:
                return branches[0]
        branch = self.branches()[0]
        return branch

    def getLatestCommit(self):
        # branch = self.branches()[0]
        branch = self.getLatestBranch()
        if self.git_commit_id:
            commit_id = self.git_commit_id[:8]
        else:
            commit_id = branch['commit']['short_id']
        # from code import interact
        # interact(local=locals())
        commit = self.project.commits.get(commit_id)
        return commit

    def getLatestCommitDiff(self):
        branch = self.getLatestBranch()
        commit_id = branch['commit']['short_id']
        commit = self.project.commits.get(commit_id)
        new_files = [i['new_path'] for i in commit.diff()]
        commit_info = {
            "short_id": commit_id,
            "diff_files": new_files,
            "branch": branch
        }
        return commit_info
    
    def commits(self):
        return self.project.commits.list()

if __name__ == '__main__':
    git_repos = GitRepos(249)
    print(git_repos.branches())
    #print(git_repos.commits())
    #print(git_repos.getLatestBranch())
